Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.IO

Public Class Form1

    Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        SetupDataGridView()
        BindGridFromXmlStore()

        'When the application is run, make sure the user has gone thru the 
        'process of creating a new application id and setting the app.config
        'with that value.  If App.config does not have the application id prompt the 
        'user to go thru the application id creation process.
        If String.IsNullOrEmpty(DCHelper.Functions.ApplicationId) Then
            Dim message As String = "Before you can run this sample application you must generate an ApplicationID and set its value in the config file." & vbLf
            message += "Please see the Readme.htm file in the same directory as this executable for instructions."

            MessageBox.Show(message, "Generate your own ApplicationID")
            Me.Close()

            'Attempt to start the default browser showing the document with steps to create 
            'a new Application ID and ignore any errors during doing so
            Try
                System.Diagnostics.Process.Start("Readme.htm")
            Catch
            End Try
            Exit Sub
        End If

        'Set the default date since when participant data needs to 
        'be downloaded to 1 month prior to today

        dateSinceToRetrieve.Value = DateTime.Now.Date.AddMonths(-1)
    End Sub

    ''' <summary>
    ''' Add Columns to the grid view and set the styles
    ''' </summary>
    Private Sub SetupDataGridView()
        'Add the 4 visible columns and one hidden column.
        'At runtime, for each row, this hidden column cell will have the currently 
        'bound ApplicationSpecificPartcipantId for the row in the "Value" property

        Dim select_column As New DataGridViewCheckBoxColumn()
        Dim name_column As New DataGridViewTextBoxColumn()
        Dim status_column As New DataGridViewTextBoxColumn()
        Dim more_info_column As New DataGridViewButtonColumn()
        Dim hidden_partcipantid_column As New DataGridViewTextBoxColumn()

        select_column.Name = "Select"
        name_column.Name = "Name"
        status_column.Name = "HasAuthorized"
        more_info_column.Name = "Details"
        hidden_partcipantid_column.Name = "MyAppSpecificParticipantId"

        hidden_partcipantid_column.Visible = False

        'All the columns except the select column is read only
        select_column.ReadOnly = False
        name_column.ReadOnly = True
        status_column.ReadOnly = True
        more_info_column.ReadOnly = False

        more_info_column.CellTemplate.Style.Padding = New Padding(2)

        'Add the 5 columns to the grid view
        participantGridView.Columns.Add(select_column)
        participantGridView.Columns.Add(name_column)
        participantGridView.Columns.Add(status_column)
        participantGridView.Columns.Add(more_info_column)
        participantGridView.Columns.Add(hidden_partcipantid_column)
    End Sub

    ''' <summary>
    ''' This function populates the current data stored in XML to the grid
    ''' </summary>
    Private Sub BindGridFromXmlStore()
        'Clear all rows first
        participantGridView.Rows.Clear()

        'Read XML and construct the data set from it
        Dim ds As DataSet = XmlStore.ConstructDataSetFromXml()

        For Each row As DataRow In ds.Tables(0).Rows
            Dim bHasUserAuthorizedApplication As Boolean = (CBool(row("HasAuthorized")) = True)

            'Construct the data for the 5 columns that the grid has
            Dim rowData As Object() = New Object(5) {}

            If bHasUserAuthorizedApplication Then
                ''For participants who has authorized the application, show checked check box 
                ''so that user can select / unselect this row 
                rowData(0) = True
            Else
                'For participants who has not authorized the application, do not
                'show the check box since we cant access their healthvault record yet
                rowData(0) = Nothing
            End If
            rowData(1) = row("ParticipantName")
            rowData(2) = row("HasAuthorized")
            rowData(3) = "View/Print"
            rowData(4) = row("MyAppSpecificParticipantId")

            'Add a row to grid
            Dim rowIndex As Integer = participantGridView.Rows.Add(rowData)

            'If the user has not authorized the application, make sure 
            'the check box is readonly and cannot be checked.
            If Not bHasUserAuthorizedApplication Then
                participantGridView.Rows(rowIndex).Cells("Select").ReadOnly = True
            Else
                participantGridView.Rows(rowIndex).Cells("Select").ReadOnly = False
            End If
        Next
    End Sub

    Private Sub Enroll_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnEnroll.Click
        Dim enrollDlg As New EnrollDlg()
        Dim dlgResult As DialogResult = enrollDlg.ShowDialog(Me)
        If dlgResult = System.Windows.Forms.DialogResult.OK Then
            'When we add a participant make sure we refresh the grid
            BindGridFromXmlStore()

            'Show the participant details so that the it can be printed
            'and handed over to the participant
            Dim objparticipantDlg As New ParticipantDlg()
            ParticipantDlg.AppSpecificParticpantId = enrollDlg.AppSpecificParticpantId
            ParticipantDlg.ShowDialog(Me)
        End If
    End Sub

    Private Sub Grid_CellPainting(ByVal sender As Object, ByVal e As DataGridViewCellPaintingEventArgs) Handles participantGridView.CellPainting
        'We need to hide DataGridViewCheckBoxCell (Select column) on some rows of the 
        'DataGridView. There is no direct way to do that. Hence override the painting
        'for that cell and do not draw it if the value (DataGridViewCheckBoxCell.Value) 
        'is null.
        If e.RowIndex = -1 Then
            'Dont do anything fancy for headers
            Exit Sub
        End If

        Dim cell As DataGridViewCell = participantGridView.Rows(e.RowIndex).Cells(e.ColumnIndex)
        If TypeOf cell Is DataGridViewCheckBoxCell Then
            'About to draw a DataGridViewCheckBoxCell
            Dim chkCell As DataGridViewCheckBoxCell = TryCast(cell, DataGridViewCheckBoxCell)
            If chkCell.Value Is Nothing Then
                e.PaintBackground(e.ClipBounds, True)
                e.Handled = True
            End If
        End If
    End Sub

    Private Sub btnSelectAll_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSelectAll.Click
        'For each row where DataGridViewCheckBoxCell is visible, make it checked
        For Each gRow As DataGridViewRow In participantGridView.Rows
            If TryCast(gRow.Cells(0), DataGridViewCheckBoxCell).Value IsNot Nothing Then
                TryCast(gRow.Cells(0), DataGridViewCheckBoxCell).Value = True
            End If
        Next
    End Sub

    Private Sub btnSelectNone_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSelectNone.Click
        'For each row where DataGridViewCheckBoxCell is invisible, make it unchecked
        For Each gRow As DataGridViewRow In participantGridView.Rows
            If TryCast(gRow.Cells(0), DataGridViewCheckBoxCell).Value IsNot Nothing Then
                TryCast(gRow.Cells(0), DataGridViewCheckBoxCell).Value = False
            End If
        Next

    End Sub

    Private Sub Grid_CellClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles participantGridView.CellClick
        'Trap the cell click function to handle the button clicks
        'when the user clicks the "View/Print" button on the grid

        If e.RowIndex = -1 Then
            'Ignore if the header is clicked
            Exit Sub
        End If

        Dim cell As DataGridViewCell = participantGridView.Rows(e.RowIndex).Cells(e.ColumnIndex)
        If TypeOf cell Is DataGridViewButtonCell Then
            'Button cell clicked
            Dim btnCell As DataGridViewButtonCell = TryCast(cell, DataGridViewButtonCell)

            'Find the application specific participant id for the row from the 
            'corresponding hidden column cell - MyAppSpecificParticipantKey
            Dim myAppSpecificParticipantId As String = btnCell.OwningRow.Cells("MyAppSpecificParticipantId").Value.ToString()

            'Show the participant details
            Dim participantDlg As New ParticipantDlg()
            participantDlg.AppSpecificParticpantId = myAppSpecificParticipantId

            Dim dlgResult As DialogResult = participantDlg.ShowDialog(Me)
        End If
    End Sub

    Private Sub btnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnUpdate.Click
        Dim checkStatusDlg As New CheckStatusDlg()
        Dim dlgResult As DialogResult = checkStatusDlg.ShowDialog(Me)

        'Rebind the grid from store again so that it will show the latest status
        BindGridFromXmlStore()
    End Sub

    Private Sub btnRetrieve_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnRetrieve.Click
        btnRetrieve.Text = "Processing..."
        btnRetrieve.Enabled = False

        Application.DoEvents()

        Try
            'Construct a list of participants whose data needs to be retrieved
            Dim participantConnectionDetailsList As New List(Of DCHelper.ParticipantConnectionDetails)
            For Each gRow As DataGridViewRow In participantGridView.Rows
                'If a row is checked (ie, value of cell is true) add it to list
                Dim select_cell As DataGridViewCheckBoxCell = TryCast(gRow.Cells(0), DataGridViewCheckBoxCell)
                If select_cell.Value IsNot Nothing AndAlso CBool(select_cell.Value) = True Then
                    Dim myAppSpecificParticipantId As String = gRow.Cells("MyAppSpecificParticipantId").Value.ToString()
                    Dim row As DataRow = XmlStore.FetchParticipantFromLocalStore(myAppSpecificParticipantId)
                    Dim personId As New System.Guid(row("PersonId").ToString())
                    Dim recordId As New System.Guid(row("RecordId").ToString())

                    Dim connectionDetail As New DCHelper.ParticipantConnectionDetails(myAppSpecificParticipantId, personId, recordId)
                    participantConnectionDetailsList.Add(connectionDetail)

                End If
            Next
            If participantConnectionDetailsList.Count = 0 Then
                MessageBox.Show("No participants selected. Please select one or more participants whose data needs to be retrieved")
                Exit Sub
            End If

            'One or more participants selected. Initialize results dialog and Show it
            'The actual retrieve of data will be done by that dialog

            Dim totalParticipants As Integer = participantGridView.Rows.Count
            Dim resultsDlg As New ResultsDlg(totalParticipants, Me.dateSinceToRetrieve.Value, participantConnectionDetailsList)

            resultsDlg.ShowDialog()
        Catch ex As Exception
            MessageBox.Show("Exception occured:" + ex.Message)
        Finally
            btnRetrieve.Text = "&Retrieve Data"
            btnRetrieve.Enabled = True
        End Try
    End Sub
End Class
